package org.jiangwei.cmput696.entitylinking.tacindex;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.MMapDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

public class TacKBService {

	private static IndexReader indexReader;
	private static IndexSearcher searcher;
	private static Analyzer analyzer;

	public TacKBService() throws IOException {
		this(TacHelper.DEFAULT_INDEX_DIR);
	}

	private TacKBService(String indexPath) throws IOException {
		// Directory dir = FSDirectory.open(new File(indexPath));
		Directory dir = new RAMDirectory(new MMapDirectory(new File(indexPath)));
		if (indexReader == null) {
			indexReader = IndexReader.open(dir);
			searcher = new IndexSearcher(indexReader);
			analyzer = new StandardAnalyzer(Version.LUCENE_34);
		}
	}

	public Document getDocByWikiName(String wikiName) throws IOException {
		Query query = new TermQuery(
				new Term(TacHelper.KEY_WIKI_TITLE, wikiName));
		return search(query);
	}

	public Document getDocById(String entityId) throws IOException {
		Query query = new TermQuery(new Term(TacHelper.KEY_ID, entityId));
		return search(query);
	}

	public Document getDocByTacName(String tacName) throws IOException {
		Query query = new TermQuery(new Term(TacHelper.KEY_TAC_TITLE, tacName));
		return search(query);
	}

	// public List<Document> searchWikiName(String wikiName)
	// throws ParseException, CorruptIndexException, IOException {
	// QueryParser parser = new QueryParser(Version.LUCENE_34,
	// TacHelper.KEY_WIKI_TITLE_FOR_SEARCH, analyzer);
	// Query query = parser.parse(wikiName);
	// return searchForList(query);
	// }

	private Document search(Query query) throws IOException,
			CorruptIndexException {
		TopDocs td = searcher.search(query, 10);
		if (td == null || td.totalHits == 0) {
			return null;
		}
		int docId = td.scoreDocs[0].doc;
		Document doc = indexReader.document(docId);
		return doc;
	}

	// private List<Document> searchForList(Query query) throws IOException,
	// CorruptIndexException {
	// TopDocs td = searcher.search(query, 200);
	// List<Document> result = new ArrayList<Document>();
	// if (td == null || td.totalHits == 0) {
	// return result;
	// }
	// // System.out.println(td.totalHits);
	// // td = searcher.search(query, td.totalHits);
	// for (int i = 0; i < td.scoreDocs.length; i++) {
	// int docId = td.scoreDocs[i].doc;
	// result.add(indexReader.document(docId));
	// }
	// return result;
	// }

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// if (args.length < 1) {
		// System.out.println("Usage: TacKBService <indexPath>");
		// System.exit(-1);
		// }
		// args = new String[] {DEFAULT_INDEX_DIR};
		// try {
		// TacKBService service = new TacKBService(args[0]);
		// Document doc = null;
		// // doc = service.getDocByWikiName("Thomasville, Georgia");
		// doc = service.getDocByWikiName("Lucy Walsh");
		// // doc = service.getDocById("E0000003");
		// //doc = service.getDocByTacName("Theodore_Roberts");
		//
		// if (doc == null) {
		// System.out.println("no hits.");
		// } else {
		// System.out.println(doc.get(TacHelper.KEY_ID));
		// System.out.println(doc.get(TacHelper.KEY_WIKI_TITLE));
		// System.out.println(doc.get(TacHelper.KEY_TAC_TITLE));
		// System.out.println(doc.get(TacHelper.KEY_FACT));
		// System.out.println(doc.get(TacHelper.KEY_TYPE));
		// System.out.println(doc.get(TacHelper.KEY_TEXT));
		// }
		//
		// } catch (IOException e) {
		// e.printStackTrace();
		// }
		try {
			TacKBService service = new TacKBService(
			// "/Users/wintokk/Dropbox/Research/cmput696/project/cmput696-asn-test/test_files/tac-kbp-sample/index");
					TacHelper.DEFAULT_INDEX_DIR);
			// List<Document> list = service.searchWikiName("Steven Gerrard");
			// List<Document> list = service.searchWikiName("Oliver Hill");
			// List<Document> list = service.searchWikiName("Frisco");
			// List<Document> list = service.searchWikiName("MoCA");
			// List<Document> list = service.searchWikiName("lucy");
			// if (list.size() > 0) {
			// for (Document doc : list) {
			// System.out.println("hit: "
			// + doc.get(TacHelper.KEY_WIKI_TITLE));
			// }
			// }
			// System.out.println("total: " + list.size());

			Document doc = service.getDocByWikiName("Steven Gerrard");
			System.out.println(doc.get(TacHelper.KEY_TEXT));
		} catch (IOException e) {
			e.printStackTrace();
			// } catch (ParseException e) {
			// e.printStackTrace();
		}
	}

}
